---@class Utility : Object
local Utility = {}

--- 根据路径读取技能
---@param package Package
Utility.loadSkillSkelsByPackage = function(package)
    local path = "./packages/ym_Al/pkg/"..package.name.."/skills"
    local skels = {}
    local normalized_dir = path
        :gsub("^%.+/", "")
        :gsub("/+$", "")
        :gsub("/", ".")
    for _, filename in ipairs(FileIO.ls(path)) do
        -- 别加载下划线开头的模板技能哈
        if filename:sub(-4) == ".lua" and filename ~= "init.lua" and not filename:startsWith("_") then
        local skel = Pcall(require, normalized_dir .. "." .. filename:sub(1, -5))
            if skel then
                -- 如果返回了一个skel表
                if type(skel) == "table" and not skel.class then
                    for _, v in ipairs(skel) do
                        if not Fk.skills[v.name] then
                            table.insert(skels, v)
                        end
                    end
                elseif not Fk.skills[skel.name] then
                    table.insert(skels, skel)
                end
            end
        end
    end
    package:loadSkillSkels(skels)
end
------------------------------------------------------------------------------------------------------
Fk:loadTranslationTable{
    ["#EnterBattlefield-log"] = "%to 进入了 〖%arg〗",
    ["#LeaveBattlefield-log"] = "%to 离开了 〖%arg〗",
    ["#EnterBattlefieldFrom-log"] = "%from 令 %to 进入了 〖%arg〗",
    ["#LeaveBattlefieldFrom-log"] = "%from 令 %to 离开了 〖%arg〗",
}
--- BattlefieldData 数据
---@class BattlefieldDataSpec
---@field public from? ServerPlayer @ 发起者
---@field public to ServerPlayer @ 玩家
---@field public tos ServerPlayer[] @ 同一批进入或离开战场的角色（列表）
---@field public battle string @ 进入或离开的战场
---@field public skill_name? string @ 原因（技能名）

---@class Utility.BattlefieldData: BattlefieldDataSpec, TriggerData
Utility.BattlefieldData = TriggerData:subclass("BattlefieldData")

--- TriggerEvent
---@class Utility.BattlefieldTriggerEvent: TriggerEvent
---@field public data Utility.BattlefieldData
Utility.BattlefieldTriggerEvent = TriggerEvent:subclass("BattlefieldEvent")

--- 进入战场
---@class Utility.EnterBattlefield: Utility.BattlefieldTriggerEvent
Utility.EnterBattlefield = Utility.BattlefieldTriggerEvent:subclass("fk.EnterBattlefield")
--- 离开战场
---@class Utility.LeaveBattlefield: Utility.BattlefieldTriggerEvent
Utility.LeaveBattlefield = Utility.BattlefieldTriggerEvent:subclass("fk.LeaveBattlefield")

---@alias BattlefieldTrigFunc fun(self: TriggerSkill, event: Utility.BattlefieldTriggerEvent,
---  target: ServerPlayer, player: ServerPlayer, data: Utility.BattlefieldData):any

---@class SkillSkeleton
---@field public addEffect fun(self: SkillSkeleton, key: Utility.BattlefieldTriggerEvent,
---  data: TrigSkelSpec<BattlefieldTrigFunc>, attr: TrigSkelAttribute?): SkillSkeleton

--- 变更战场
--- @param room Room @ 游戏房间
--- @param from? ServerPlayer @ 发起角色
--- @param tos ServerPlayer | ServerPlayer[] @ 进入或离开战场的角色（列表）
--- @param battle string @ 进入或离开的战场
--- @param skill_name? string @ 技能名
Utility.changeBattlefield = function (room, from, tos, battle, skill_name)
    local Enter, Leave, Change = {}, {}, {}
    if tos.class then tos = { tos } end
    for _, cp in ipairs(tos) do
        if cp:getMark("@[:]Battlefield") ~= battle then
            if cp:getMark("@[:]Battlefield") ~= 0 then
                table.insert(Change,{cp.id,cp:getMark("@[:]Battlefield")})
            end
            table.insert(Enter,cp.id)
            room:setPlayerMark(cp,"@[:]Battlefield",battle)
        else
            table.insert(Leave,cp.id)
            room:setPlayerMark(cp,"@[:]Battlefield",0)
        end
    end
    if from then
        if #Enter > 0 then
            room:sendLog{type = "#EnterBattlefieldFrom-log",from = from.id,to = Enter,arg = battle,toast = true,}
        end
        if #Leave > 0 then
            room:sendLog{type = "#LeaveBattlefieldFrom-log",from = from.id,to = Leave,arg = battle,toast = true,}
        end
    else
        if #Enter > 0 then
            room:sendLog{type = "#EnterBattlefield-log",to = Enter,arg = battle,toast = true,}
        end
        if #Leave > 0 then
            room:sendLog{type = "#LeaveBattlefield-log",to = Leave,arg = battle,toast = true,}
        end
    end
    for _, value in ipairs(Change) do
        local player = room:getPlayerById(value[1])
        local leaveBattle = value[2]
        room.logic:trigger(Utility.LeaveBattlefield, player, {to = player, tos = tos, battle = leaveBattle, from = from, skill_name = skill_name})
    end
    for _, id in ipairs(Enter) do
        local player = room:getPlayerById(id)
        room.logic:trigger(Utility.EnterBattlefield, player, {to = player, tos = tos, battle = battle, from = from, skill_name = skill_name})
    end
    for _, id in ipairs(Leave) do
        local player = room:getPlayerById(id)
        room.logic:trigger(Utility.LeaveBattlefield, player, {to = player, tos = tos, battle = battle, from = from, skill_name = skill_name})
    end
end

return Utility